package com.sxyc.weixin.controller;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.amitek.service.bean.protocol.PosInfo;
import com.amitek.service.bean.protocol.TrackInfo;
import com.amitek.service.bean.response.PosResult;
import com.amitek.service.bean.response.TrackDesc;
import com.amitek.service.bean.response.TrackList;
import com.amitek.service.bean.response.TrackStatus;
import com.jfinal.core.Controller;
import com.jfinal.kit.PropKit;
import com.jfinal.weixin.sdk.api.SnsAccessToken;
import com.jfinal.weixin.sdk.api.SnsAccessTokenApi;
import com.sxyc.tintin.controller.CommonController;
import com.sxyc.tintin.model.DeviceBinding;
import com.sxyc.tintin.model.HideTrack;
import com.sxyc.tintin.model.WxUser;
import com.sxyc.tintin.sdk.SDKUtils;
import com.sxyc.utils.DateUtil;
import com.sxyc.utils.ResultUtils;

public class TracksController extends Controller {

	// 使用jFinal 日志
	private static com.jfinal.log.Log log = com.jfinal.log.Log.getLog(CommonController.class);

	/**
	 * 通用版 行使轨迹
	 */
	public void index(){
		String code = getPara("code");
    	String openId = (String) getRequest().getSession().getAttribute("openId");
    	if(openId == null && code == null){
			String url = SnsAccessTokenApi.getAuthorizeURL(PropKit.get("appId"), PropKit.get("domain")+"/track", true);
			redirect(url);
		}else{
			if(openId == null){
				SnsAccessToken accessToken = SnsAccessTokenApi.getSnsAccessToken(PropKit.get("appId"), PropKit.get("appSecret"),code);
				openId = accessToken.getOpenid();
				getRequest().getSession().setAttribute("openId", openId);
			}
			DeviceBinding user = DeviceBinding.dao.getWxUserByOpenId(openId);
			if(user==null){
				renderJsp("bind.jsp");
			}else{
				setAttr("deviceId", user.get("deviceId"));
				renderJsp("tracks.jsp");
			}
		}
	}
	
	/**
	 * 行使轨迹
	 */
	public void getTracks(){
		long deviceId = getParaToLong("deviceId");
		long start = getParaToLong("start");
		long end = getParaToLong("end");
		if(end <= start) {
			renderJson(ResultUtils.getFailureResult(400, "not found tracks"));
	    }else{
	    	List<JSONObject> list = new ArrayList<JSONObject>();
			//获取trackList
	    	TrackList trackList = SDKUtils.getTrackList(deviceId, start, end);
	    	System.out.println("trackList : "+trackList);
	    	if(trackList == null){
	    		renderJson(ResultUtils.getFailureResult(400, "not found tracks"));
	    		return;
	    	}
	    	List<HideTrack> hideTrackList = HideTrack.dao.find("select trackId from hidetrack where deviceId = ?",
	    			new Object[] {deviceId});
	    	System.out.println(trackList);
			//用 track.trackId 获取trackStatus
	    	for (TrackDesc track : trackList) {
	    		boolean ishide = false;
	    		for (HideTrack hideTrack : hideTrackList) {
					if(hideTrack.getStr("trackid").equals(track.trackId+"")){
						ishide = true;break;
					}
				}
	    		if(ishide)	continue;//此行程已被隐藏，跳过本次操作
				if(track.trackFinished && track.trackStop >0l){
					TrackStatus trackStatus = SDKUtils.getTrackStatus(deviceId,track.trackId);
					//获取成绩
					JSONObject json = new JSONObject();
					JSONObject statistics = new JSONObject();
					if(trackStatus.trackInfo != null && trackStatus.trackInfo.totalMileage != null && trackStatus.trackInfo.totalMileage > 0){
						TrackInfo trackInfo = trackStatus.trackInfo;
						int score = getTracksScore(trackInfo.turnoverCnt, trackInfo.accelerateCnt, trackInfo.decelerateCnt, trackInfo.overspeedCnt);
						double avgSpeed = ((double)trackInfo.totalMileage / 1000)/((double)(trackStatus.trackDesc.trackStop - trackStatus.trackDesc.trackStart) / (1000*60*60));
				    	statistics.put("totalMileage", (double)trackInfo.totalMileage / 1000);
				    	statistics.put("maxSpeed", trackStatus.trackInfo.maxSpeed);
				    	statistics.put("avgSpeed", new BigDecimal(avgSpeed).setScale(2, RoundingMode.HALF_UP).doubleValue());
				    	statistics.put("score", score);
					}
					json.put("desc", track);
					json.put("statistics", statistics);
					list.add(json);
				}
			}

//          System.out.println("tracks~~~~~~~~~~~~~~~~~~~~");
//			System.out.println(list.toString());
			
			
			if(list != null && list.size()>0){
			   String startDate = DateUtil.getDate(start);
	           String endDate = DateUtil.getDate(end);
	           log.info("startDate is ["+startDate+"] endDate is ["+endDate+"]");
	           List<JSONObject> dailys = new ArrayList<JSONObject>();
	           do{
	        	   JSONObject daily = new JSONObject();
	        	   daily.put("date", startDate);
	        	   dailys.add(daily);
	        	   startDate = DateUtil.getTomorrowDate(startDate);
	            } while(DateUtil.getDateByLong(startDate) <= DateUtil.getDateByLong(endDate));	            

//	            System.out.println("dailys~~~~~~~~~~~~~~~~~~~~");
//	            System.out.println(dailys.toString());
	            int sumSize = 0;
	            int sumScores = 0;
	            double sumSpeeds = 0;
	            double sumMileages = 0;
	            for (JSONObject daily : dailys) {
	            	int size = 0;
	            	int scores = 0;
		            double speeds = 0;
		            double mileages = 0;
		            JSONArray tracks = new JSONArray();
		            for (JSONObject track : list) {
		            	TrackDesc desc = (TrackDesc) track.get("desc");
		            	JSONObject statistics = JSONObject.parseObject(track.getString("statistics"));
		            	String tempDate = DateUtil.getDate(desc.trackId);
		            	if(tempDate.equals(daily.get("date"))){
		            		size++;
		            		sumSize++;
		            		scores += statistics.getIntValue("score");
		            		speeds += statistics.getDoubleValue("avgSpeed");
		            		mileages += statistics.getDoubleValue("totalMileage");
		            		sumScores += statistics.getIntValue("score");
		            		sumSpeeds += statistics.getDoubleValue("avgSpeed");
		            		sumMileages += statistics.getDoubleValue("totalMileage");
		            		JSONObject obj = new JSONObject();
		            		obj.put("desc", desc);
		            		obj.put("statistics", statistics); 
		            		tracks.add(obj);
		            	}
					}
//		            scores = scores>0 ? Math.round(scores/size) : 100;
//		            speeds = speeds>0 ? new BigDecimal(speeds/size).setScale(2, RoundingMode.HALF_UP).doubleValue() : 0;
		            daily.put("mileages", new BigDecimal(mileages).setScale(2, RoundingMode.HALF_UP).doubleValue());
		            daily.put("score", scores>0 ? Math.round(scores/size) : 100);
		            daily.put("speed", speeds>0 ? new BigDecimal(speeds/size).setScale(2, RoundingMode.HALF_UP).doubleValue() : 0);
		            daily.put("tracks", tracks);
				}
	            JSONObject sum = new JSONObject();
	            sum.put("mileages", new BigDecimal(sumMileages).setScale(2, RoundingMode.HALF_UP).doubleValue());
	            sum.put("score", sumScores>0 ? Math.round(sumScores/sumSize) : 100);
	            sum.put("speed", sumSpeeds>0 ? new BigDecimal(sumSpeeds/sumSize).setScale(2, RoundingMode.HALF_UP).doubleValue() : 0);
	            JSONObject data = new JSONObject();
	            data.put("dailys", dailys);
	            data.put("sum", sum);
	            renderJson(ResultUtils.getSuccessResult(200, "ok", data));
	        }else{
	        	renderJson(ResultUtils.getFailureResult(400, "not found tracks"));
	        }
	    }
	}

	/**
	 * 获取轨迹点
	 */
	public void searchPoss(){
		long deviceId = getParaToLong("deviceId");
		long trackId = getParaToLong("trackId");
		long start = getParaToLong("start");
		long end = getParaToLong("end");
		if(end <= start) {
			renderJson(ResultUtils.getFailureResult(400, "not found tracks"));
	    }else{
	    	PosResult postInfo = SDKUtils.getPosInfos(deviceId, trackId, start, end);
	        log.info("postInfo : "+postInfo);
	        if(postInfo != null && postInfo.recordList.size()>0){
	            List<PosInfo> recordList = postInfo.recordList;
	            List<JSONObject> data = new ArrayList<JSONObject>();
	            for (PosInfo posInfo : recordList) {
	            	JSONObject pos = new JSONObject();
	            	pos.put("lat", posInfo.latitude);
	            	pos.put("lng", posInfo.longitude);
	            	data.add(pos);
				}
	            
	            renderJson(ResultUtils.getSuccessResult(200, "ok", data));
	        }else{
	        	renderJson(ResultUtils.getFailureResult(400, "not found tracks"));
	        }
	    }
	}
	
	public void hideTrack(){
		long deviceId = getParaToLong("deviceId");
		long trackId = getParaToLong("trackId");
		new HideTrack().set("deviceId", deviceId).set("trackId", trackId).save();
		renderJson(ResultUtils.getSuccessResult());
	}
	
	/**
	 * 获取score
	 * @param turnoverCnt
	 * @param accelerateCnt
	 * @param decelerateCnt
	 * @param overspeedCnt
	 * @return
	 */
	private int getTracksScore(int turnoverCnt, int accelerateCnt, int decelerateCnt, int overspeedCnt) {
		int score = 0;
		if(turnoverCnt > 0){
			score = 40;
		}else{
			int temp = accelerateCnt*3 + decelerateCnt*3 + overspeedCnt*7;
			if(temp > 40)
				score = 40;
			else
				score = temp;
		}
		return 100 - score;
	}
}
